module("luci.controller.web.system", package.seeall)

local md5 = require "md5"
local ip = require "luci.ip"
local json = require "cjson.safe"
local uci  = require "luci.model.uci".cursor()

function index()
	local page = node("web", "system")
	page.target = firstchild()
	
	entry({"web", "system"}, alias("web", "system", "index"), _("index"), 10).index = true
	
	entry({"web", "system", "index"}, template("web/index"), 1)
	
-----------------------------------菜单导航----------------------------------
	-- 联网设置页面
	entry({"web", "system", "mnetwork"}, template("web/network"), 2)
	-- WIFI设置页面
	entry({"web", "system", "mwifi"}, template("web/wifi"), 3)
	-- 设备管理页面
	entry({"web", "system", "mdevices"}, template("web/devices"), 4)
	-- 防火墙页面
	entry({"web", "system", "mfirewall"}, template("web/firewall"), 5)
	-- 常规设置页面
	entry({"web", "system", "mconfig"}, template("web/config"), 6)
	-- 云盘页面
    entry({"web", "system", "mdisk"}, template("web/disk"), 7)
	
-----------------------------------路由状态----------------------------------
	-- 获取系统静态数据
	entry({"web", "system", "sysinfo"}, call("system_info"), nil)
	-- 获取网络状态
	entry({"web", "system", "wanstatus"}, call("wan_status"), nil)
	-- 获取系统动态数据
	entry({"web", "system", "sysstatus"}, call("system_status"), nil)

-----------------------------------联网设置----------------------------------
	-- 获取WAN参数
	entry({"web", "system", "wan"}, call("wan_get"), nil)
	-- 获取WAN状态
	entry({"web", "system", "waninfo"}, call("wan_info"), nil)
	-- WAN临时开关
	entry({"web", "system", "wanswitch"}, call("wan_switch"), nil)
	-- 设置WAN参数
	entry({"web", "system", "wanset"}, call("wan_set"), nil)

	
-----------------------------------WIFI设置----------------------------------
	-- 获取WIFI参数
	entry({"web", "system", "wifi"}, call("wifi_get"), nil)
	-- 设置WIFI参数
	entry({"web", "system", "wifiset"}, call("wifi_set"), nil)

	
-----------------------------------设备管理----------------------------------
	-- 获取设备列表
	entry({"web", "system", "devices"}, call("link_devices"), nil)
	-- 限速处理
	entry({"web", "system", "speed"}, call("speed_limit"), nil)
	-- 拉黑处理
	entry({"web", "system", "blacklist"}, call("blacklist_set"), nil)


----------------------------------- 防火墙 ----------------------------------
	-- 获取防火墙参数
	entry({"web", "system", "filter"}, call("filter_get"), nil)
	-- 获取列表
	entry({"web", "system", "getrules"}, call("get_filter_list"), nil)
	-- 增删列表
	entry({"web", "system", "setrules"}, call("set_filter_list"), nil)
	-- 设置防火墙参数
	entry({"web", "system", "filterset"}, call("filter_set"), nil)
	
-----------------------------------常规设置----------------------------------
	-- 修改密码
	entry({"web", "system", "passwdset"}, call("passwd_set"), nil)
	
	-- 重启路由器
	entry({"web", "system", "reboot"}, call("reboot_act"), nil)
	-- 恢复出厂设置
	entry({"web", "system", "factory"}, call("factory_reset"), nil)
	-- 版本比较
	entry({"web", "system", "checkver"}, call("version_check"), nil)
	-- 远程升级
	entry({"web", "system", "rupgrade"}, call("remote_upgrade"), nil)
	-- 本地升级
	entry({"web", "system", "lupgrade"}, call("local_upgrade"), nil)
	-- 下载日志
	entry({"web", "system", "syslog"}, call("syslog_get"), nil)

end

-- 获取系统静态数据
function system_info()
	local code=0
	local data={}
	local msg="Success"
	
	data["sn"] = uci:get("web", "system", "sn")
	data["mac"] = uci:get("web", "system", "mac")
	data["model"] = uci:get("web", "system", "model")
	data["fwver"] = uci:get("web", "system", "fwver")
	
	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 获取网络状态
function wan_status()
	local code=0
	local data={}
	local msg="Success"
	
	local result = os.execute("ping 114.114.114.114 -c 1 -w 5 -W 5 | grep ttl 1>/dev/null 2>&1")
	if result == 0 then
		data["wanstatus"] = '1'
	else
		data["wanstatus"] = '0'
	end
	
	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 获取系统动态数据
function system_status()
	local code=0
	local data={}
	local msg="Success"
	
	local devices = get_devices()
	data["linkcount"] = #devices
	
	local wan = get_wan_info()
	data["wanuptime"] = wan["uptime"]
	
--[[	local result = os.execute("ping 114.114.114.114 -c 1 -w 1 | grep ttl 1>/dev/null 2>&1")
	if result == 0 then
		data["wanstatus"] = '1'
	else
		data["wanstatus"] = '0'
	end--]]
	
	data["wanspeed"] = get_wan_speed()
	
	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 恢复出厂设置
function factory_reset()
	local code=0
	local msg="Success"
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	os.execute("sleep 5 && jffs2reset -y && reboot -d 3 &")
end

-- 固件版本检测
function version_check()
	local data={}
	local code=1
	local force=false
	local msg="正在检测"
	
	data["upgrade"] = 0
	data["ver"]=uci:get("web", "system", "fwver")

	local url = "http://www.zeerong.com/router/web/config/version/luci"

	luci.sys.exec("echo url=" .. url .. ">>/tmp/txt")

	local result = luci.sys.exec("curl -s \""..url.."\"")

	local jsonobj = json.decode(result)
	luci.sys.exec("echo result=" .. result .. ">>/tmp/txt")
	if jsonobj then
		local ver_array = split(data["ver"], '.')
		local ver=tonumber(ver_array[1]..ver_array[2]..ver_array[3])
		
		data["version"] = jsonobj["versionCode"]
		local version_array = split(data["version"], '.')
		local version=tonumber(version_array[1]..version_array[2]..version_array[3])
		luci.sys.exec("echo version=" .. version .. ">>/tmp/txt")
		luci.sys.exec("echo ver=" .. ver .. ">>/tmp/txt")
		if version > ver then
			code=0
			msg="检测到升级固件"
			data["upgrade"] = 1
			data["md5"]=jsonobj["md5"]
			data["url"]=jsonobj["downUrl"]
			data["log"]=jsonobj["updateLog"]
			data["vername"]=jsonobj["versionName"]
			data["force"]=jsonobj["bForceUpdata"]
			force = jsonobj["bForceUpdata"]
		else
			code=1
			msg="没有检测到升级固件"
		end
	else
		code = 1
		msg = "正在检测"
	end
	
--[[	if code == 0 and force == true then
		local filename = "firmware.bin"
		local result = os.execute("curl -o /tmp/"..filename.." -s -m 30 "..data['url'].."")
		if result == 0 then
			md5str=luci.sys.exec("md5sum /tmp/"..filename.." | awk '{printf $1}'")
			if md5str == data["md5"] then
				local ret=os.execute("sysupgrade -T /tmp/"..filename)
				if ret ~= 0 then
					code=1
					msg="无法识别固件,请稍后再试"
				else
					code=0
					msg="路由器在升级过程中请勿断电、刷新或关闭页面,否则会导致升级失败。"
					-- LED灯闪烁 + 升级
					os.execute("sleep 5 && sysupgrade -n /tmp/"..filename.." &")
				end
			else
				code=1
				msg="文件检验异常,请稍后再试"
			end
		else
			code=1
			msg="下载异常,请稍后再试"
		end
	end
--]]	
	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 远程固件升级
function remote_upgrade()
	local data={}
	local code=1
	local msg="下载异常,请稍后再试"
	
	local url = luci.http.formvalue("url")
	local md5value = luci.http.formvalue("md5")
	local keep = luci.http.formvalue("keep") or '0'
	local filename = "firmware.bin"
	
	local result = os.execute("curl -o /tmp/"..filename.." -s "..url.."")
	if result == 0 then
		md5str=luci.sys.exec("md5sum /tmp/"..filename.." | awk '{printf $1}'")
		if md5str == md5value then
			local ret=os.execute("sysupgrade -T /tmp/"..filename)
			if ret ~= 0 then
				code=1
				msg="无法识别固件,请稍后再试"
			else
				code=0
				msg="路由器在升级过程中请勿断电、刷新或关闭页面,否则会导致升级失败。"
			end
		else
			code=1
			msg="文件检验异常,请稍后再试"
		end
	else
		code=1
		msg="下载异常,请稍后再试"
	end
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)

	if code == 0 then
	-- LED灯闪烁 + 升级
		if keep == '1' then
			os.execute("sleep 5 && sysupgrade /tmp/"..filename.." &")
		else
			os.execute("sleep 5 && sysupgrade -n /tmp/"..filename.." &")
		end
	end
end

-- 本地固件升级
function local_upgrade()
	local data={}
	local code=1
	local msg="Success"
	
	local fs = require "nixio.fs"
	
	local canupload = true
    local uploadFile = "/tmp/firmware.bin"
    local filesize = tonumber(luci.http.getenv("CONTENT_LENGTH"))

	if filesize < 5242880 then			-- < 5MB
		canupload = false
		code=1
		msg="固件太小,请检查后再提交"
	elseif filesize > 16777216 then		--  > 16MB
		canupload = false
		code=1
		msg="固件太大,请检查后再提交"
	end
	
	fs.unlink(uploadFile)

    luci.http.setfilehandler(
        function(meta, chunk, eof)
            if canupload then
                if not fp then
                    if meta and meta.name == "firmware" then
                        fp = io.open(uploadFile, "w")
                    end
                end
                if chunk then
                    fp:write(chunk)
                end
                if eof then
                    fp:close()
					local ret=os.execute("sysupgrade -T "..uploadFile)
					if ret ~= 0 then
						code=1
						msg="无法识别固件,请检查后再提交"
					else
						code=0
						msg="正在升级ing"
					end
                end
            end
        end
    )
	
	luci.http.formvalue("firmware")
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	local keep = luci.http.formvalue("keep") or '0'
	
	if code == 0 then
	-- LED灯闪烁 + 升级
		if keep == '1' then
			os.execute("sleep 5 && sysupgrade "..uploadFile.." &")
		else
			os.execute("sleep 5 && sysupgrade -n "..uploadFile.." &")
		end
	end
end

-- 重启设备
function reboot_act()
	local code=0
	local msg="Success"
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	os.execute("reboot -d 5 &")
end

-- 修改密码
function passwd_set()
	local code=0
	local msg="Success"
	
	local passwd = luci.http.formvalue("passwd")
	local newpasswd = luci.http.formvalue("newpasswd")
	local newpasswd2 = luci.http.formvalue("newpasswd2")
	local password = uci:get("web", "login", "passwd")
	
	if passwd and newpasswd and newpasswd2 then
		if passwd ~= password then
			code=1
			msg="原密码不正确,请检查后再提交"
		elseif passwd == newpasswd then
			code=1
			msg="新密码与原密码相同,请检查后再提交"
		elseif newpasswd ~= newpasswd2 then
			code=1
			msg="两次输入不一致,请检查后再提交"
		elseif passwd == password and newpasswd == newpasswd2 then
			uci:set("web", "login", "passwd", newpasswd)
		end
	else
		code=1
		msg="密码为空,请检查后再提交"
	end
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("web")
	end
end

-- 获取局域网参数
function lan_get()
	local code=0
	local msg="success"
	local data={}
	
	data["ipaddr"] = uci:get("network","lan","ipaddr")				--	局域网IP地址
	data["force"] = uci:get("dhcp","lan","force") or '1'			--	DHCP开关,关闭:0 开启:1
	data["start"] = uci:get("dhcp","lan","start")					--	DHCP开始IP
	data["end"] = uci:get("dhcp","lan","limit")
	data["end"] = data["start"] + data["end"] - 1					--	DHCP结束IP
	data["leasetime"] = uci:get("dhcp","lan","leasetime")			--	DHCP租约期时间
	data["leasetime"] = string.sub(data["leasetime"], 0, string.len(data["leasetime"])-1)	--  截取字符串
	
	local addr = get_ipaddr(data["ipaddr"])
	if addr then
		data["addr"] = addr[1].."."..addr[2].."."..addr[3]
	end

	data ={ 
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 设置局域网IP地址
function lan_set()
	local code=0
	local msg="success"
	
	local ipaddr = luci.http.formvalue("ipaddr")
	
	if not ipaddr then
		msg="IP地址为空,请检查后再提交"
	elseif not ip.IPv4(ipaddr) then
		code=1
		msg="IP地址错误,请检查后再提交"
	else
		uci:set("network", "lan", "ipaddr", ipaddr)
	end
	
	data ={ 
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("network")
		os.execute("reboot -d 3 &")
	end

end

-- 设置DHCP参数
function dhcp_set()
	local code=0
	local msg="success"
	
	local force = luci.http.formvalue("force") or "0"
	local start = tonumber(luci.http.formvalue("start"))
	local stop = tonumber(luci.http.formvalue("end"))
	local leasetime = tonumber(luci.http.formvalue("leasetime"))

	if force == "1" then							-- 开启
		uci:set("dhcp", "lan", "force", "1")
		uci:set("dhcp", "lan", "ignore", "0")
	elseif force == "0" then						-- 禁用
		uci:set("dhcp", "lan", "force", "0")
		uci:set("dhcp", "lan", "ignore", "1")
	else
		code=1
		msg="无法识别,请检查后再提交"
	end
	
	if not start then
		code = 1
		msg = "开始IP为空,请检查后再提交"
	elseif not stop then
		code = 1
		msg = "结束IP为空,请检查后再提交"
	elseif not leasetime then
		code = 1
		msg = "租约期为空,请检查后再提交"
	else
		local limit = stop - start + 1
		uci:set("dhcp", "lan", "start", start)
		uci:set("dhcp", "lan", "limit", limit)
		uci:set("dhcp", "lan", "leasetime", leasetime.."m")
	end
	
	data ={ 
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("dhcp")
		os.execute("/etc/init.d/dnsmasq reload")
	end

end

-- 获取WAN状态
function wan_info()
	local code=0
	local msg="Success"
	
	local data=get_wan_info()
	
	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- WAN临时开关
function wan_switch()
	local code=0
	local msg="Success"
	local act=tonumber(luci.http.formvalue("act") or '0')
	
	if act == 1 then
		os.execute("ifup wan")
	elseif act == 0 then
		os.execute("ifdown wan")
	else
		code=1
		msg="未知模式,请检查后再提交"
	end
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 获取WAN参数
function wan_get()
	local code=0
	local msg="success"
	local data={}

	local ifname = uci:get("network", "wan", "ifname")
	data["proto"] = uci:get("network","wan","proto")							--	上网方式 DHCP:dhcp 静态IP:static PPPOE:pppoe 
	
	data["ipaddr"] = uci:get("network","wan","ipaddr")							--	静态IP地址
	data["netmask"] = uci:get("network","wan","netmask")						--	静态IP子网掩码
	data["gateway"] = uci:get("network","wan","gateway")						--	静态网关地址
	data["username"]  = uci:get("network","wan","username")						--	PPPOE 用户名
	data["password"]  = uci:get("network","wan","password")						--	PPPOE 密码
	data["mtu"]  = uci:get("network","wan","mtu")								--	PPPOE MTU
	data["autoset"] = "0"                                  					 	--	0表示自动，1表示手动
	
	local dns = uci:get("network","wan","dns")
	local dnsaddr=strtok(dns)													-- 根据空格划分成2个字符串
	
	if dnsaddr then		
		data["dns1"]=dnsaddr[1]													--	DNS1
		data["dns2"]=dnsaddr[2]													--	DNS2
		data["autoset"] = "1"													--  有DNS值,表示手动
	end

	data ={ 
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 联网设置
function wan_set()
	local code=0
	local msg="success"
	
	local lan_ipaddr = uci:get("network", "lan", "ipaddr")
	local proto = luci.http.formvalue("proto") or "dhcp"
	local autoset = luci.http.formvalue("autoset") or "0"
	local dns1 = luci.http.formvalue("dns1")
	local dns2 = luci.http.formvalue("dns2")
	local mtu = luci.http.formvalue("mtu")
	local username = luci.http.formvalue("username")
	local password = luci.http.formvalue("password")
	local ipaddr = luci.http.formvalue("ipaddr")		--	静态IP地址
	local netmask = luci.http.formvalue("netmask")		--	静态IP子网掩码
	local gateway = luci.http.formvalue("gateway")		--	静态网关地址
	
	local dns = strcat(dns1, dns2)
	
	if proto == "static" then
		local flag=check_same_ip(lan_ipaddr, ipaddr)
		if not ip.IPv4(ipaddr) then
			code = 1
			msg = "IP地址错误,请检查后再提交"
		elseif not ip.IPv4(netmask) then
			code = 1
			msg = "子网掩码错误,请检查后再提交"
		elseif not ip.IPv4(gateway) then
			code = 1
			msg = "网关地址错误,请检查后再提交"
		elseif not dns then
			code = 1
			msg = "DNS地址为空,请检查后再提交"
		elseif flag == true then
			code = 1
			msg = "WAN口的IP地址与LAN口IP地址冲突,请检查后再提交"
		else
			uci:set("network", "wan", "proto", "static")
			uci:set("network", "wan", "ipaddr", ipaddr)
			uci:set("network", "wan", "netmask", netmask)
			uci:set("network", "wan", "gateway", gateway)
			uci:set("network", "wan", "dns", dns)
		end
	elseif proto == "pppoe" then
		if not username then
			code = 1
			msg = "用户名为空,请检查后再提交"
		elseif not password then
			code = 1
			msg = "密码为空,请检查后再提交"
		else
			uci:set("network", "wan", "proto", "pppoe")
			uci:set("network", "wan", "username", username)
			uci:set("network", "wan", "password", password)
		end
		
		if autoset == "1" then
			if not dns then
				code = 1
				msg = "DNS地址为空,请检查后再提交"
			elseif mtu < 64 or mtu > 1528 then
				code = 1
				msg = "MTU值错误,请检查后再提交"
			else
				uci:set("network", "wan", "mtu", mtu)
				uci:set("network", "wan", "dns", dns)
			end
		else
			uci:delete("network", "wan", "dns")
		end
	else
		uci:set("network", "wan", "proto", "dhcp")
		
		if autoset == "1" then
			if not dns then
				code = 1
				msg = "DNS地址为空,请检查后再提交"
			else
				uci:set("network", "wan", "dns", dns)
			end
		else
			uci:delete("network", "wan", "dns")
		end
	end
	
	if not mtu then
		uci:delete("network", "wan", "mtu")
	end
	
	if not dns then
		uci:delete("network", "wan", "dns")
	end
	
	data ={ 
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("network")
		os.execute("sleep 3 && /etc/init.d/network restart &")
	end
end

-- 获取WIFI参数
function wifi_get()
	local code=0
	local msg="success"
	local data={}
	
	-- 2.4G参数
	data["ra0"]={}
	data["ra0"]["disabled"] = uci:get("wireless","ra0","disabled") or '0'			-- WIFI开关: 1是禁用,0是启用
	data["ra0"]["ssid"] = uci:get("wireless","ra0","ssid") or ''					-- SSID：长度最长32位
	data["ra0"]["key"] = uci:get("wireless","ra0","key") or ''						-- 秘钥:长度最少8位
	data["ra0"]["encryption"] = uci:get("wireless","ra0","encryption") or 'none'	-- 加密方式: none/psk-mixed/psk2
	data["ra0"]["hidden"] = uci:get("wireless","ra0","hidden") or '0'				-- 隐藏: 1隐藏

	-- 5.8G参数
	data["rai0"]={}
	data["rai0"]["disabled"] = uci:get("wireless","rai0","disabled") or '0'			-- WIFI开关: 1是禁用,0是启用
	data["rai0"]["ssid"] = uci:get("wireless","rai0","ssid") or ''					-- SSID：长度最长32位
	data["rai0"]["key"] = uci:get("wireless","rai0","key") or ''						-- 秘钥:长度最少8位
	data["rai0"]["encryption"] = uci:get("wireless","rai0","encryption") or 'none'	-- 加密方式: none/psk-mixed/psk2
	data["rai0"]["hidden"] = uci:get("wireless","rai0","hidden") or '0'				-- 隐藏: 1隐藏

	-- 访客参数
	data["ra1"]={}
	data["ra1"]["disabled"] = uci:get("wireless","ra1","disabled") or '0'			-- WIFI开关: 1是禁用,0是启用
	data["ra1"]["ssid"] = uci:get("wireless","ra1","ssid") or ''					-- SSID：长度最长32位
	data["ra1"]["key"] = uci:get("wireless","ra1","key") or ''						-- 秘钥:长度最少8位
	data["ra1"]["encryption"] = uci:get("wireless","ra1","encryption") or 'none'	-- 加密方式: none/psk-mixed/psk2
	data["ra1"]["hidden"] = uci:get("wireless","ra1","hidden") or '0'				-- 隐藏: 1隐藏
	
	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- WIFI设置
function wifi_set()
	local code=0
	local msg="success"
	
	local iface = luci.http.formvalue("iface") 								-- ra0,2.4G   rai0,5.8G		ra1,访客
	local disabled = luci.http.formvalue("disabled") or "1"
	local ssid = luci.http.formvalue("ssid") or ''
	local key = luci.http.formvalue("key") or ''
	local encryption = luci.http.formvalue("encryption") or 'none'
	local hidden = luci.http.formvalue("hidden") or '0'
	
	if #ssid > 32 then
		code=1
		msg = "SSID为空或者长度超过32位,请检查后再提交"
	end

	if encryption ~= "none" then
		if #key < 8 or #key > 63 then
			code=1
			msg="密码长度小于8或者超过63位,请检查后再提交"
		end
	end
	
	uci:set("wireless", iface, "disabled", disabled)
	uci:set("wireless", iface, "ssid", ssid)
	uci:set("wireless", iface, "key", key)
	uci:set("wireless", iface, "encryption", encryption)
	uci:set("wireless", iface, "hidden", hidden)

	
	data ={ 
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("wireless")
		--os.execute("wifi down && sleep 1 && wifi up &")
		os.execute("sleep 3 && /etc/init.d/network restart &")
	end
end

-- 系统日志
function syslog_get()
	local code=0
	local msg="Success"
	local data=luci.sys.syslog()
	
	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 联网终端
function link_devices()
	local code=0
	local msg="success"
	
	local data = get_devices()
	local count = #data
	
	data ={ 
		data=data,
		count=count,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 限速处理
function speed_limit()
	local flag=0
	local code=0
	local msg="success"
	
	local ipaddr = luci.http.formvalue("ipaddr")
	local macaddr = luci.http.formvalue("macaddr")
	local uplimit = tonumber(luci.http.formvalue("uplimit") or '0')
	local downlimit = tonumber(luci.http.formvalue("downlimit") or '0')
	
	if not ipaddr then
		code = 1
		msg = "IP地址为空,请检查后再提交"
	elseif not macaddr then
		code = 1
		msg = "MAC地址为空,请检查后再提交"
	else
		uci:foreach("speed", "limit", function(s)							
			local lcName = s[".name"]
			local mac = uci:get("speed", lcName, "mac")
			
			if mac and mac == macaddr then
				flag=1
				if uplimit == 0 and downlimit == 0 then						-- 限速均为0,删除
					uci:delete("speed", lcName)
				else														-- 更新限速数据
					uci:set("speed", lcName, "ip", ipaddr)
					uci:set("speed", lcName, "uplimit", uplimit)
					uci:set("speed", lcName, "downlimit", downlimit)
				end
			end
		end)
		
		uci:foreach("dhcp", "host", function(s) 
			local lcName = s[".name"]
			local ip = uci:get("dhcp", lcName, "ip")
			local mac = uci:get("dhcp", lcName, "mac")
			local remark = uci:get("dhcp", lcName, "remark")

			if mac and mac == macaddr then
				if uplimit == 0 and downlimit == 0 then
					uci:delete("dhcp", lcName)
				else
					uci:set("dhcp", lcName, "ip", ipaddr)                                                  
					uci:set("dhcp", lcName, "mac", macaddr)
				end
			end                           
		end)

		if flag == 0 then				-- 增加
			if uplimit ~= 0 or downlimit ~= 0 then
				local lcName = uci:add("speed", "limit")
				uci:set("speed", lcName, "ip", ipaddr)
				uci:set("speed", lcName, "mac", macaddr)
				uci:set("speed", lcName, "uplimit", uplimit)
				uci:set("speed", lcName, "downlimit", downlimit)
				
				local lcName = uci:add("dhcp", "host")
				uci:set("dhcp", lcName, "ip", ipaddr)                                                  
				uci:set("dhcp", lcName, "mac", macaddr)
				uci:set("dhcp", lcName, "remark", "Auto")
			end
		end
	end
	
	data ={ 
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("speed")
		uci:commit("dhcp")
		os.execute("/etc/init.d/dnsmasq reload")
		os.execute("/usr/sbin/speedlimit.sh start")
	end
end

-- 拉黑处理
function blacklist_set()
	local flag=0
	local code=0
	local msg="success"
	
	local macaddr = luci.http.formvalue("mac")
	local hostname = luci.http.formvalue("hostname")
	local access = luci.http.formvalue("access") or '1'
	
	local enable=uci:get("filter", "list", "enable")  					-- 防火墙开关. 禁用:0 启用:1
	local rule=uci:get("filter", "list", "rule")  						-- 防火墙规则. 拒绝:deny  允许:allow
	
	if enable ~= '1' or rule ~= "deny" then
		code=1
		msg="防火墙规则拒绝模式未开启"
	else
		if access == "1" then											-- 删除
			-- 轮询删除列表数据
			uci:foreach("filter", "deny", function(s)							
				local lcName = s[".name"]
				local mac = uci:get("filter", lcName, "mac")
				
				if mac and mac == macaddr then
					uci:delete("filter", lcName)
				end
			end)
			
			-- 轮询删除防火墙数据
			uci:foreach("firewall", "rule", function(s)							
				local lcName = s[".name"]
				local name = uci:get("firewall", lcName, "name")			
				local mac = uci:get("firewall", lcName, "src_mac")

				if name and name == "FilterRule" and mac and mac == macaddr then
					uci:delete("firewall", lcName)
				end
			end)			
		else
			-- 修改
			uci:foreach("filter", rule, function(s)							
				local lcName = s[".name"]
				local macaddr = uci:get("filter", lcName, "mac")				-- MAC地址
				local name = uci:get("filter", lcName, "name")					-- 描述

				if mac == macaddr then
					flag=1
					if hostname then
						uci:set("filter", lcName, "name", hostname)				-- 描述
					end
				end
			end)
			-- 增加
			if flag == 0 then
				local lcName = uci:add("filter", rule)
				uci:set("filter", lcName, "mac", mac)							-- MAC地址
				if hostname then
					uci:set("filter", lcName, "name", hostname)					-- 描述
				end
				
				local lcName = uci:add("firewall", "rule")
				uci:set("firewall", lcName, "src", "lan")
				uci:set("firewall", lcName, "dest", "wan")
				uci:set("firewall", lcName, "proto", "tcpudp")
				uci:set("firewall", lcName, "name", "FilterRule")
				uci:set("firewall", lcName, "target", "REJECT")
				uci:set("firewall", lcName, "src_mac", macaddr)
				
			end
		end
	end
	
	data ={ 
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("filter")
		uci:commit("firewall")
		os.execute("/etc/init.d/firewall restart")
	end
end

-- 防火墙规则
function filter_get()
	local data={}
	local code=0
	local msg="Success"
	local count=1
	
	data["list"]={}
	data["filter"]={}
	data["filter"]["enable"]=uci:get("filter", "list", "enable") or '0'  				-- 防火墙开关. 禁用:0 启用:1
	data["filter"]["rule"]=uci:get("filter", "list", "rule") or 'deny'					-- 防火墙规则. 拒绝:deny  允许:allow
	
	if data["filter"]["rule"] == "allow" or data["filter"]["rule"] == "deny" then		-- 获取列表数据
		uci:foreach("filter", data["filter"]["rule"], function(s)							
			local lcName = s[".name"]
			data["list"][count]={}
			data["list"][count]["mac"] = uci:get("filter", lcName, "mac")				-- MAC
			data["list"][count]["name"] = uci:get("filter", lcName, "name")				-- 描述
			count=count+1
		end)

		data["filter"]["count"]=count-1													-- 总个数
	else
		data["filter"]["count"]=0														-- 总个数
	end

	data ={
		code=code,
		msg=msg,
		data=data
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 获取规则列表
function get_filter_list()
	local data={}
	local code=0
	local msg="Success"
	local count=1
	
	local rule = luci.http.formvalue("rule")								-- deny,获取拒绝列表  allow,获取允许列表

	data["list"]={}
	data["filter"]={}
	if rule == "allow" or rule == "deny" then
		uci:foreach("filter", rule, function(s)							
			local lcName = s[".name"]
			data["list"][count]={}
			data["list"][count]["mac"] = uci:get("filter", lcName, "mac")			-- MAC地址
			data["list"][count]["name"] = uci:get("filter", lcName, "name")			-- 描述
			count=count+1
		end)
	else
		code=1
		msg="未知模式,请检查后再提交"
	end
	
	data["filter"]["count"]=count-1

	data ={
		data=data,
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
end

-- 设置规则列表
function set_filter_list()
	local flag=0
	local code=0
	local msg="Success"
	local json = require "cjson.safe"
	
	local rule = luci.http.formvalue("rule")
	local act = luci.http.formvalue("act")
	local mac = luci.http.formvalue("mac")
	local name = luci.http.formvalue("name")
	

	if rule ~= "allow" and rule ~= "deny" then
		code=1
		msg="无法识别,请检查后再提交"
	end
		
	if	act == "0" then														-- 添加
		-- 修改
		uci:foreach("filter", rule, function(s)							
			local lcName = s[".name"]
			local macaddr = uci:get("filter", lcName, "mac")				-- MAC地址
--			local name = uci:get("filter", lcName, "name")					-- 描述

			if mac == macaddr then
				flag=1
				if name then
					uci:set("filter", lcName, "name", name)					-- 描述
				end
			end
		end)
		-- 增加
		if flag == 0 then
			local lcName = uci:add("filter", rule)
			uci:set("filter", lcName, "mac", mac)							-- MAC地址
			if name then
				uci:set("filter", lcName, "name", name)						-- 描述
			end
		end
	else
		uci:foreach("filter", rule, function(s)							
			local lcName = s[".name"]
			local macaddr = uci:get("filter", lcName, "mac")				-- MAC地址
			local name = uci:get("filter", lcName, "name")					-- 描述

			if act == "2" or mac == macaddr then
				uci:delete("filter", lcName)
			end
		end)
	end
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("filter")
	end
end

-- 设置防火墙参数
function filter_set()
	local code=0
	local msg="Success"
	local count=0
	local maclist = {}
	
	local enable = luci.http.formvalue("enable") or "0"
	local rule = luci.http.formvalue("rule")
	
	uci:set("filter", "list", "enable", enable)
	uci:set("filter", "list", "rule", rule)
	
	-- 轮询删除防火墙数据
	uci:foreach("firewall", "rule", function(s)							
		local lcName = s[".name"]
		local name = uci:get("firewall", lcName, "name")

		if name and name == "FilterRule" then
			uci:delete("firewall", lcName)
		end
	end)
	
	if enable == "1" then
		uci:foreach("filter", rule, function(s)							
				local lcName = s[".name"]
				local macaddr = uci:get("filter", lcName, "mac")					-- MAC地址
				local name = uci:get("filter", lcName, "name")						-- 描述

				local lcName = uci:add("firewall", "rule")
				uci:set("firewall", lcName, "src", "lan")
				uci:set("firewall", lcName, "dest", "wan")
				uci:set("firewall", lcName, "proto", "tcpudp")
				uci:set("firewall", lcName, "name", "FilterRule")
				uci:set("firewall", lcName, "src_mac", macaddr)
				
				if rule == "allow" then
					uci:set("firewall", lcName, "target", "ACCEPT")
				else
					uci:set("firewall", lcName, "target", "REJECT")
				end
		end)
		
		if rule == "allow" then
			local lcName = uci:add("firewall", "rule")
			uci:set("firewall", lcName, "src", "lan")
			uci:set("firewall", lcName, "dest", "wan")
			uci:set("firewall", lcName, "target", "REJECT")
			uci:set("firewall", lcName, "name", "FilterRule")
		end
	end
	
	data ={
		code=code,
		msg=msg
	}
	luci.http.prepare_content("application/json")
	luci.http.write_json(data)
	
	if code == 0 then
		uci:commit("filter")
		uci:commit("firewall")
		os.execute("/etc/init.d/firewall restart")
	end
	
end


-------------------------API---------------------------------

-- 比较IP地址网段,是否一致
function check_same_ip(self, ip1, ip2)
	local addr1=get_ipaddr(ip1)
	local addr2=get_ipaddr(ip2)

	if not ip1 or not ip2 then
		return false
	elseif addr1[1] == addr2[1] and addr1[2] == addr2[2] and addr1[3] == addr2[3] then
		return true
	else
		return false
	end
end

--截取IP地址
function get_ipaddr(ipaddr)
	local ipaddrs={}
	local num=1
	
	if type(ipaddr) == "string" and ipaddr ~= nil then
		for addr in string.gmatch(ipaddr, "%d+") do
			ipaddrs[num]=addr
			num=num+1
		end
	
		if ipaddrs[1] ~= nil and ipaddrs[2] ~= nil and ipaddrs[3] ~= nil and ipaddrs[4] ~= nil then
			return ipaddrs
		end
	end

	return nil
end

-- 根据字符,分割字符串
function split(str, reps)
    local res = {}
    string.gsub(str,'[^'..reps..']+',function ( w )
        table.insert(res,w)
    end)
    return res
end

-- 根据空格划分成2个字符串
function strtok(str)
	local array={}
	
	if not str then
		return nil
	else
		for tmp in string.gmatch(str, "%S+") do									
			table.insert(array, tmp)
		end
		return array
	end
end

-- 合并DNS
function strcat(str1, str2)
	local str

	if str1 and str2 then
		str = str1.." "..str2
	elseif str1 then
		str = str1
	elseif str2 then
		str = str2
	else 
		str = nil
	end
	
	return str
end

-- 自动检测WAN口的工作模式: PPPOE or DHCP
function wan_link_probe()
    local line = luci.sys.exec("/bin/linkprobe 1 WAN pppoe dhcp")

    local link,pppoe,dhcp

	if line:match("^LINK=(%S+)") ~= nil then
		link = line:match("^LINK=(%S+)")
	elseif line:match("^PPPOE=(%S+)") ~= nil then
		pppoe = line:match("^PPPOE=(%S+)")
	elseif line:match("^DHCP=(%S+)") ~= nil then
		dhcp = line:match("^DHCP=(%S+)")
	end

    if pppoe == "YES" then
        return 1
    elseif dhcp == "YES" then
        return 2
    elseif link ~= "YES" then
        return 99
    else
        return 0
    end
end

-- 获取WAN状态
function get_wan_info()
	local interface = "wan"
	local info = {}
	info["proto"] = ""
	info["ip"] = ""
	info["mask"] = ""
	info["gateWay"] = ""
	info["mac"] = ""
	info["dnsAddrs1"] = ""
	info["dnsAddrs2"] = ""
	info["uptime"] = 0
	
    local LuciNetwork = require("luci.model.network").init()
	local ubus = require("ubus").connect()
	local wan = ubus:call("network.interface."..interface, "status", {})
    local ifname = uci:get("network",interface,"ifname")
	
	info["up"] = wan["up"]
	
    local network = LuciNetwork:get_network(interface)
    if network then
        local device = network:get_interface()
        local ipAddrs = device:ipaddrs()
		
        if device and #ipAddrs > 0 then
            local ipAddress = {}
            for _,ip in ipairs(ipAddrs) do
                ipAddress[#ipAddress+1] = {}
                info["ip"] = ip:host():string()
                info["mask"] = ip:mask():string()
				
            end
        end
		
		info["proto"] = network:proto()
        info["gateWay"] = network:gwaddr()
		
        if network:dnsaddrs() then
            info["dnsAddrs1"] = network:dnsaddrs()[1] or ""
            info["dnsAddrs2"] = network:dnsaddrs()[2] or ""
        else
            info["dnsAddrs1"] = ""
            info["dnsAddrs2"] = ""
        end
		
        if device and device:mac() ~= "00:00:00:00:00:00" then
            info["mac"] = device:mac()
        end

        if network:uptime() > 0 then
            info["uptime"] = network:uptime()
        else
            info["uptime"] = 0
        end
    end
    return info
end


-- 查询是否可以访问外网
function check_device_access(macaddr)
	local flag="1"
	
	local enable=uci:get("filter", "list", "enable")  					-- 防火墙开关. 禁用:0 启用:1
	local rule=uci:get("filter", "list", "rule")  						-- 防火墙规则. 拒绝:deny  允许:allow
	
	if enable ~= '1' or rule ~= "deny" then
		return flag
	end
	
	if not macaddr then
		return flag
	end
	
	uci:foreach("filter", rule, function(s)							
		local lcName = s[".name"]
		local mac = uci:get("filter", lcName, "mac")				-- MAC地址

		if mac == macaddr then
			flag="0"
		end
	end)
	
--[[	uci:foreach("firewall", "rule", function(s)							
		local lcName = s[".name"]
		local name = uci:get("firewall", lcName, "name")			
		local mac = uci:get("firewall", lcName, "src_mac")

		if name and name == "FilterRule" and mac and mac == macaddr then
			flag="0"
		end
	end)--]]

	return flag
end

-- 查询是否有限速
function check_device_limit(macaddr)
	local uplimit=0
	local downlimit=0

	uci:foreach("speed", "limit", function(s)							
		local lcName = s[".name"]
		local mac = uci:get("speed", lcName, "mac")
		
		if mac and mac == macaddr then
			uplimit=uci:get("speed", lcName, "uplimit")
			downlimit=uci:get("speed", lcName, "downlimit")
		end
	end)
	
	return uplimit,downlimit
end

-- 获取联网客户端
function get_devices(self)
	local data={}
	local count=1
	local file="/tmp/.flow/data"

	luci.sys.exec("ps | grep ipbandwidth.sh | grep -v grep >/dev/null 2>&1 || /usr/sbin/ipbandwidth.sh &")
	
	local fd = io.open(file, "r")
	if fd then
		while true do
			local ln = fd:read("*l")
			if not ln then
				break
			else
				local res = split(ln, '|')
				if res then
					local macaddr = res[2]
					local online = tonumber(res[5])
					
					if online == 1 then
						local access = check_device_access(macaddr)
						local uplimit,downlimit = check_device_limit(macaddr)
						
						data[#data+1] = {
							ipaddr	   	= res[1],
							macaddr	  	= res[2],
							linktime 	= res[3],
							hostname 	= res[4],
							upspeed  	= res[7],
							downspeed 	= res[8],
							access		= access,
							uplimit 	= uplimit,
							downlimit 	= downlimit
						}
					end
				end
			end
		end
		fd:close()
	end
	
	return data
end

function get_wan_speed()
	local wan = {}
	local json = require "cjson.safe"
	local ifname = uci:get("network", "wan", "ifname") or "eth1"
	local nowtime=os.time() - 5
	local datatime = 0
	local upspeed = 0
	local dwspeed = 0
	local upflow = 0
	local dwflow = 0
	local lastupflow = 0
	local lastdwflow = 0 
	local lasttime = 0
	local maxupspeed = 0
	local maxdwspeed = 0
	
	local data = action_bandwidth(ifname)
	local josnObj = json.decode(data)
	if josnObj then	
		for i=1, #(josnObj) do
			local array = josnObj[i]
			if array[1] >= nowtime then
				datatime = array[1]
				dwflow = array[2]
				upflow = array[4]
				
				if lasttime ~= 0 then
					dwspeed = math.floor((dwflow - lastdwflow) / (datatime - lasttime))
					upspeed = math.floor((upflow - lastupflow) / (datatime - lasttime))
				end
				
				maxdwspeed = math.max(maxdwspeed, dwspeed)
				maxupspeed = math.max(maxupspeed, upspeed)
				
				lasttime = datatime
				lastdwflow = dwflow
				lastupflow = upflow
			end
		end
	end
	
	-- 当前时间戳
	wan["time"] = lasttime
	-- 10s内最大下载速度,单位bytes/s
	wan["dwspeed"] = maxdwspeed
	-- 10s内最大上传速度,单位bytes/s
	wan["upspeed"] = maxupspeed
	-- 总下载流量,单位bytes
	wan["dwflow"] = dwflow
	-- 总上传流量,单位bytes
	wan["upflow"] = upflow
	
	return wan
end

-- 获取流量
function action_bandwidth(iface)
	local bw = ""

	local bwc = io.popen("luci-bwc -i %q 2>/dev/null" % iface)
	if bwc then
		bw = "["
		while true do
			local ln = bwc:read("*l")
			if not ln then break end
			bw = bw..ln
		end
		bw = bw.."]"
		bwc:close()
	end
	
	return bw
end